# -*- coding: utf-8 -*-
"""
Markdown解析步骤
负责解析输入的Markdown文件，提取结构和内容
"""

import logging
from pathlib import Path
from typing import Dict, Any, List
import re

from ..step_base import BaseStep, StepResult

logger = logging.getLogger(__name__)


class ParseMarkdownStep(BaseStep):
    """Markdown解析步骤"""

    name = "parse_markdown"
    description = "解析Markdown文件，提取结构化内容"
    required_inputs = ["markdown_file"]
    optional_inputs = []
    produces_outputs = ["parsed_content", "scene_list"]

    def __init__(self, markdown_file: Path, output_dir: Path, **kwargs):
        """
        初始化步骤

        Args:
            markdown_file: Markdown文件路径
            output_dir: 输出目录
        """
        super().__init__(output_dir, **kwargs)
        self.markdown_file = Path(markdown_file)

    def validate_inputs(self) -> tuple[bool, list[str]]:
        """验证输入"""
        errors = []

        if not self.markdown_file.exists():
            errors.append(f"Markdown file not found: {self.markdown_file}")

        if not self.markdown_file.suffix.lower() in [".md", ".markdown"]:
            errors.append(f"Invalid file type: {self.markdown_file.suffix}")

        return len(errors) == 0, errors

    def run(self) -> StepResult:
        """执行步骤"""
        try:
            self.report_progress(0, "Reading markdown file")

            # 读取文件
            with open(self.markdown_file, "r", encoding="utf-8") as f:
                content = f.read()

            # 解析内容
            self.report_progress(30, "Parsing markdown structure")

            parsed_content = self._parse_markdown(content)
            scene_list = self._extract_scenes(parsed_content)

            # 保存结果
            self.report_progress(70, "Saving parsed content")

            self._save_results(parsed_content, scene_list)

            # 完成
            self.report_progress(100, "Markdown parsed successfully")

            return StepResult(
                success=True,
                message="Markdown parsed successfully",
                data={
                    "markdown_file": str(self.markdown_file),
                    "total_scenes": len(scene_list),
                    "parsed_content": parsed_content,
                },
                output_files=[
                    self.output_dir / "parsed_content.json",
                    self.output_dir / "scene_list.json",
                ],
            )

        except Exception as e:
            logger.exception("Failed to parse markdown")
            return StepResult(
                success=False,
                message=f"Failed to parse markdown: {str(e)}",
            )

    def _parse_markdown(self, content: str) -> Dict[str, Any]:
        """
        解析Markdown内容

        Args:
            content: Markdown内容

        Returns:
            解析后的内容
        """
        lines = content.split("\n")
        parsed = {
            "title": "",
            "sections": [],
            "metadata": {},
            "raw_content": content,
        }

        current_section = None
        in_code_block = False
        code_block_type = ""
        code_content = []

        for i, line in enumerate(lines):
            # 处理代码块
            if line.strip().startswith("```"):
                if not in_code_block:
                    in_code_block = True
                    code_block_type = line.strip()[3:].strip()
                    code_content = []
                else:
                    # 结束代码块
                    if current_section:
                        current_section["content"].append({
                            "type": "code",
                            "language": code_block_type,
                            "content": "\n".join(code_content),
                        })
                    in_code_block = False
                    code_block_type = ""
                    code_content = []
                continue

            if in_code_block:
                code_content.append(line)
                continue

            # 处理标题
            if line.startswith("#"):
                level = len(line) - len(line.lstrip("#"))
                title_text = line.lstrip("#").strip()

                if level == 1 and not parsed["title"]:
                    parsed["title"] = title_text
                else:
                    # 创建新段落
                    current_section = {
                        "level": level,
                        "title": title_text,
                        "content": [],
                    }
                    parsed["sections"].append(current_section)

            # 处理列表项
            elif line.strip().startswith("- ") or line.strip().startswith("* "):
                if current_section:
                    current_section["content"].append({
                        "type": "list",
                        "text": line.strip()[2:].strip(),
                    })

            # 处理图片
            elif line.strip().startswith("!["):
                if current_section:
                    # 提取图片信息
                    match = re.match(r'!\[(.*?)\]\((.*?)\)', line.strip())
                    if match:
                        alt_text, image_path = match.groups()
                        current_section["content"].append({
                            "type": "image",
                            "alt": alt_text,
                            "path": image_path,
                        })

            # 处理普通文本
            elif line.strip() and current_section:
                current_section["content"].append({
                    "type": "text",
                    "text": line.strip(),
                })

        # 提取元数据
        parsed["metadata"] = self._extract_metadata(content)

        return parsed

    def _extract_metadata(self, content: str) -> Dict[str, Any]:
        """
        提取元数据

        Args:
            content: Markdown内容

        Returns:
            元数据字典
        """
        metadata = {}

        # 提取front matter（如果存在）
        if content.startswith("---"):
            end_front_matter = content.find("---", 3)
            if end_front_matter != -1:
                front_matter = content[3:end_front_matter]
                # 简单的YAML解析（仅支持简单键值对）
                for line in front_matter.split("\n"):
                    if ":" in line:
                        key, value = line.split(":", 1)
                        metadata[key.strip()] = value.strip()

        return metadata

    def _extract_scenes(self, parsed_content: Dict[str, Any]) -> List[Dict[str, Any]]:
        """
        提取场景列表

        Args:
            parsed_content: 解析后的内容

        Returns:
            场景列表
        """
        scenes = []

        # 创建标题场景
        if parsed_content["title"]:
            scenes.append({
                "type": "title",
                "title": parsed_content["title"],
                "subtitle": parsed_content["metadata"].get("subtitle", ""),
                "order": 0,
            })

        # 为每个段落创建场景
        for i, section in enumerate(parsed_content["sections"]):
            # 如果段落有标题
            if section["title"]:
                scene = {
                    "type": "text",
                    "title": section["title"],
                    "content": [],
                    "order": i + 1,
                }

                # 添加内容
                for item in section["content"]:
                    if item["type"] == "text":
                        scene["content"].append(item["text"])
                    elif item["type"] == "list":
                        scene["content"].append(f"• {item['text']}")
                    elif item["type"] == "code":
                        scene["content"].append({
                            "type": "code",
                            "language": item.get("language", "python"),
                            "content": item["content"],
                        })
                    elif item["type"] == "image":
                        scene["content"].append({
                            "type": "image",
                            "path": item["path"],
                            "alt": item["alt"],
                        })

                scenes.append(scene)

        return scenes

    def _save_results(self, parsed_content: Dict[str, Any], scene_list: List[Dict[str, Any]]):
        """
        保存结果

        Args:
            parsed_content: 解析后的内容
            scene_list: 场景列表
        """
        import json

        # 保存解析内容
        with open(self.output_dir / "parsed_content.json", "w", encoding="utf-8") as f:
            json.dump(parsed_content, f, indent=2, ensure_ascii=False)

        # 保存场景列表
        with open(self.output_dir / "scene_list.json", "w", encoding="utf-8") as f:
            json.dump(scene_list, f, indent=2, ensure_ascii=False)
